package network;


import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

// udp版本的回显服务器
public class UdpEchoServer {
    // 网络编程，本质上是对网卡进行操作
    // 但是网卡不方便操作 在操作系统中 抽象 一个 socket 这样的文件来抽象表示网卡
    private DatagramSocket socket  = null;

    public UdpEchoServer(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }

    public void start() throws IOException {
        System.out.println("============ 服务器启动！==========");
        while(true){
            // 只要客户端有请求，就可以提供服务
            // 1. 确认客户端的请求
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(requestPacket); // receive 方法的参数是一个输出型参数，需要先构造好一个空白的DatagramPacket对象，然后交给receive对其进行填充
            // 此时这个dataframPacket是一个特殊的对象，并不方便直接进行处理，可以把数据拿出来，构造成一个字符串
            String request = new String(requestPacket.getData(),0, requestPacket.getLength());
            //2. 根据请求，计算，得到响应
            String response = process(request);
            // 3. 构造响应并且写回给客户端
            // requestPacket.getSocketAddress() 获取到客户端的ip和端口号
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,requestPacket.getSocketAddress());
            socket.send(responsePacket);

            // 4 打印当前这次请求响应的处理中间结果
            System.out.printf("[%s:%d] req: %s  ;  resp :%s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);
        }
    }

    // 对数据的响应进行计算操作
    public String process(String request){
        // 这里没有对数据进行处理，省略了服务器的具体业务，只是对客户端的请求做一个回显
        return request;
    }


    public static void main(String[] args) throws IOException {
        UdpEchoServer server = new UdpEchoServer(9090); // 端口号1024-65535
        server.start();
    }
}
